package com.demo.base;

import com.baomidou.mybatisplus.core.conditions.query.*;
import com.baomidou.mybatisplus.core.mapper.*;
import com.baomidou.mybatisplus.core.metadata.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.*;
import com.baomidou.mybatisplus.extension.service.impl.*;
import com.google.common.collect.*;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.*;
import org.springframework.data.jpa.repository.*;
import org.springframework.web.bind.annotation.*;
import com.util.*;

import java.lang.reflect.*;
import java.util.Arrays;
import java.util.List;

/**
 * AIKA
 */

public class BaseController<T extends BaseModel, R extends JpaRepository,
        D extends BaseMapper, S extends ServiceImpl> {

    @Autowired
    protected S service;
    @Autowired
    protected R repository;
    @Autowired
    protected D dao;

    @PostMapping("/findAll")
    public Object findAll() {
        return repository.findAll();
    }

    @PostMapping("/insert")
    public Object insert(@RequestBody T model) {
        repository.save(model.setId(null));
        return detail(model.getId().toString());
    }

    @PostMapping("/insertMask")
    public Object insertMask() {
        T model = ModelUtil.randomModel(clazz(this, 0));
        repository.save(model);
        return model;
    }

    @PostMapping("/update")
    public Object update(@RequestBody T model) {
        repository.save(model);
        return model;
    }

    @PostMapping("/detail")
    public Object detail(String id) {
        return service.getById(id);
    }

    @PostMapping("/delete")
    public Object delete(String... ids) {
        service.removeBatchByIds(Lists.newArrayList(ids));
        return Msg.Success;
    }

    @ApiOperation(value = "deleteByIds")
    @PostMapping("/deleteByIds")
    public Object deleteByIds(String... ids) {
        List<String> list = Arrays.asList(ids);
        return service.removeBatchByIds(list);
    }

    @ApiOperation(value = "deleteAll")
    @PostMapping("/deleteAll")
    public Object deleteAll() {
        List list = service.list();
        return  service.removeByIds(list);
    }

    @PostMapping("/page")
    public Object page(@RequestBody BaseDto dto) {
        IPage<T> page = Page.of(dto.getPageNum(), dto.getPageSize());
        QueryWrapper wrapper = factory().baseWrapper.base(clazz(this, 0), dto);
        return service.page(page, wrapper);
    }

    @Autowired
    private MyFactory myFactory;

    public BaseFactory factory() {
        return myFactory.factory;
    }

    private static <T> Class<T> clazz(Object obj, int index) {
        return (Class<T>) ((ParameterizedType) obj.getClass().getGenericSuperclass()).getActualTypeArguments()[index];
    }
}
